﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PixelWarfare
{
    class BlobMenuItem : IMenuItem
    {
        #region Fields

        private Bitmap img;
        private BlobField blobField;

        private Point[] points;
        private Color[] colors;
        private int speed;

        private bool needsUpdate;       // If the blob needs to be reset.
        private bool inColor;           // If the next set of blobs are color or black and white.

        private bool mouseOver;         // If the mouse is over the menu item.
        private Rectangle bounds;       // The rectangle the menu item occupies.
        private OnClick clickEvent;     // The method that runs when the button is clicked.

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new SelectionMenuItem with the given parameters.
        /// </summary>
        /// <param name="text">"Main item text"</param>
        /// <param name="x">"X coordinate to center at."</param>
        /// <param name="y">"X coordinate to center at."</param>
        /// <param name="font">"Font to draw the text with."</param>
        /// <param name="onColor">"Color when the mouse is over the item."</param>
        /// <param name="offColor">"Color when the mouse is not over the item."</param>
        /// <param name="clicked">"Method to run when the item is clicked."</param>
        public BlobMenuItem(Bitmap img, int x, int y, Point[] points, int speed, OnClick clicked)
        {
            this.img = img;

            // Setup the blob field.
            blobField = new BlobField(img.Width, img.Height);
            blobField.ActivateMap(img);

            this.speed = speed;
            this.points = points;
            
            // Colors used in game.
            colors = new Color[] { Color.FromArgb(0xCD, 0, 0), Color.MediumBlue, 
                Color.Purple, Color.Green, Color.Yellow};

            // Centre the item around the given point.
            bounds = new Rectangle(x - img.Width / 2, y - img.Height / 2, img.Width, img.Height);

            mouseOver = false;
            needsUpdate = false;
            inColor = true;

            clickEvent = clicked;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Draw the text centered at the given coordinates.
        /// </summary>
        /// <param name="g">The graphics to drawn on.</param>
        public void Draw(Graphics g)
        {
            g.DrawImage(img, bounds);

            if (mouseOver)
            {
                g.DrawImage(blobField.GetImage(), bounds);
                if (needsUpdate)
                {
                    blobField.Restart(false);
                    AddBlobs(inColor);
                    needsUpdate = false;
                }
            }

        }

        /// <summary>
        /// If the mouse is over the item then change mouse over to true
        /// which causes the text to be drawn in the onColor.
        /// Otherwise set it to be false and the text is drawn in the offColor.
        /// </summary>
        /// <param name="x">X coordinate of the mouse.</param>
        /// <param name="y">X coordinate of the mouse.</param>
        public void MouseMove(int x, int y)
        {
            if (bounds.Contains(x, y) && !mouseOver)
            {
                mouseOver = true;
                inColor = true;
                blobField.Restart();
                AddBlobs(inColor);
                
            }
            else if(!bounds.Contains(x, y) &&mouseOver)
            {
                mouseOver = false;
                needsUpdate = false;
            }
        }

        /// <summary>
        /// If the mouse is pressed check if its on the text,
        /// if so run the clickEvent.
        /// </summary>
        /// <param name="x">X coordinate of the mouse click.</param>
        /// <param name="y">X coordinate of the mouse click.</param>
        public void MousePress(int x, int y)
        {
            if (bounds.Contains(x, y))
            {
                clickEvent();
            }
        }

        /// <summary>
        /// Update the blobs in the item.
        /// </summary>
        public void Update() 
        {
            if (mouseOver)
            {
                if (blobField.Update())
                {
                    needsUpdate = true;
                    inColor = !inColor;
                }
            }
        }

        #endregion

        private void AddBlobs(bool color)
        {
            blobField.FlushBlobs();
            int index = 0;

            // Add all the given points as blobs.
            foreach (Point p in points)
            {
                if (color)
                {
                    blobField.AddBlob(p.X, p.Y, 0, speed, 1, colors[index]);
                    index = (index + 1) % colors.Length;
                }
                else
                {
                    blobField.AddBlob(p.X, p.Y, 0, speed, 1, Color.Black);
                }
            }
        }
    }
}
